import createShieldMaterial from "@/materials/createShieldMaterial.js";
import { ExtrudeGeometry, Mesh, Shape, Vector3 } from "three";
import { SHAPE_TYPES } from "cannon-es";
import debounce from "@/utils/debounce.js";
import { gsap } from "gsap";

export default class Shield {
  constructor(physics, modelMesh) {
    this.physics = physics;
    this.material = createShieldMaterial();
    this.main = this.createMesh(modelMesh);
    this.createPhysicsBody();
  }

  createMesh(modelMesh) {
    const shape = new Shape();
    const position = modelMesh.geometry.attributes.position;
    const points = [];
    for (let i = 0; i < position.count; i++) {
      const point = new Vector3(
        position.array[i * 3],
        position.array[i * 3 + 1],
        position.array[i * 3 + 2]
      );
      if (!points.length) {
        shape.moveTo(point.x, point.y);
      } else {
        shape.lineTo(point.x, point.y);
      }
      points.push(point);
    }
    const geometry = new ExtrudeGeometry(shape, { depth: 3, bevelEnabled: false });
    const mesh = new Mesh(geometry, this.material);
    mesh.position.copy(modelMesh.position);
    return mesh;
  }

  createPhysicsBody() {
    const physicsBody = this.physics.createBody({
      mesh: this.main,
      shapeType: SHAPE_TYPES.BOX,
      mass: 0
    });
    physicsBody.addEventListener("collide", () => {
      this.show();
    });
    return physicsBody;
  }

  show = debounce(() => {
    gsap.timeline()
      .to(this.material.uniforms.uHeight, { value: 3.0, duration: .5 })
      .to(this.material.uniforms.uHeight, { value: .0, duration: 2 });
  }, 3000);
}